package util

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
)

type RestResp struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data"`
}

type GraphqlResp struct {
	Data   interface{} `json:"data"`
	Errors []struct {
		Message string `json:"message"`
	} `json:"errors"`
}

const (
	SUCCESS                   = 10000
	FAIL                      = 10001
	REQUEST_PARAM_ERROR       = 20001
	DATA_SEARCH_ERROR         = 20002
	DATA_INSERT_ERROR         = 20003
	DATA_UPDATE_ERROR         = 20004
	DATA_DELETE_ERROR         = 20005
	UPLOAD_ERROR              = 30001
	DOWNLOAD_ERROR            = 30002
	FILE_GENERATE_ERROR       = 30010
	FILE_READ_ERROR           = 30011
	REMOTE_CLI_EXEC_ERROR     = 40001
	REMOTE_CLI_TIMEOUT_ERROR  = 40002
	REMOTE_DEPLOY_ERROR       = 40003
	REMOTE_GEN_TOKEN_ERROR    = 40004
	AUTH_USRER_PASS_NOT_MATCH = 50001
	AUTH_LOGIN_TIMEOUT        = 50002
)

func Success(c *gin.Context, msg string, data interface{}) {

	c.JSON(http.StatusOK,
		RestResp{
			Code:    SUCCESS,
			Message: msg,
			Data:    data,
		})
}

func Fail(c *gin.Context, code int, msg string, data interface{}) {

	c.JSON(http.StatusOK,
		RestResp{
			Code:    code,
			Message: msg,
			Data:    data,
		})
}

func RewriteBody(resp *http.Response) error {
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	err = resp.Body.Close()
	if err != nil {
		return err
	}

	var gResp GraphqlResp
	var rResp RestResp

	err = json.Unmarshal(b, &gResp)
	if err != nil {
		return err
	}
	// fmt.Printf("%v\n", gResp)

	if gResp.Errors != nil {
		rResp = RestResp{
			Code:    FAIL,
			Message: gResp.Errors[0].Message,
			Data:    gResp.Data,
		}
	} else {
		rResp = RestResp{
			Code:    SUCCESS,
			Message: "",
			Data:    gResp.Data,
		}
	}

	nb, err := json.Marshal(&rResp)
	if err != nil {
		return err
	}
	body := ioutil.NopCloser(bytes.NewReader(nb))
	resp.Body = body
	resp.ContentLength = int64(len(nb))
	resp.Header.Set("Content-Length", strconv.Itoa(len(nb)))
	return nil
}
